﻿#define 自动更新
//#define 自动更新

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;
using System.IO;
using System.Xml;
using System.Configuration;
using TierService;
using System.Runtime.InteropServices;
using TierApplication;


namespace CodePortal
{
    public partial class frmLiveUpdate : TierService.frmTemplate
    {
        [DllImport("User32.dll", EntryPoint = "SendMessage")]
        private static extern int SendMessage(int hWnd, int Msg, int wParam, int lParam);
        [DllImport("User32.dll", EntryPoint = "ReleaseCapture")]
        private static extern int ReleaseCapture();


        private IniFile mIniFile;
        private delegate void OutPutMsgDelegate(string msg);
        private delegate void OnClose();

        private Thread th = null;
        private FtpInfo _ftpInfo;
        public FtpInfo FtpInfo
        {
            get { return _ftpInfo; }
            set { _ftpInfo = value; }
        }
        private string _callbackEXE;
        public string CallBackEXE
        {
            get { return _callbackEXE; }
            set { _callbackEXE = value; }
        }
        private FTPClient _ftpClient;

        static readonly string LogFileName = "updlog.txt";
        private bool _isFinishUpdate = false;

        public frmLiveUpdate()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 开始更新
        /// </summary>
        private void BeginUpdate()
        {
            OutPutMsgAndWriteLog("正在连接更新服务器并下载程序......");
            _ftpClient = new FTPClient(_ftpInfo);

            try
            {
                _ftpClient.Connect();
            }
            catch (Exception ex)
            {
                OutPutMsgAndWriteLog("连接FTP服务器失败！错误信息：" + ex.Message);
                this.Invoke(new OutPutMsgDelegate(this.OutPutMsg), "更新程序将在10秒钟后自动关闭。");
                _isFinishUpdate = true;
                Thread.Sleep(3000);
                this.Invoke(new OnClose(DoClose));//子线程中关闭主线程创建的对象
                //CloseWindowDelay(10000);
                return;
            }


            if (!_ftpClient.Connected)
            {
                OutPutMsgAndWriteLog("连接更新服务器失败。");
                this.Invoke(new OutPutMsgDelegate(this.OutPutMsg), "更新程序将在10秒钟后自动关闭。");
                _isFinishUpdate = true;
                Thread.Sleep(3000);
                this.Invoke(new OnClose(DoClose));
                return;
            }

            if (Directory.Exists("updatetemp")) //创建更新缓存文件夹
                Directory.Delete("updatetemp", true);
            Directory.CreateDirectory("updatetemp");

            bool DownLoadError = false;
            bool DownOneError = false;
            string sSoftwareName = "";
            int iLocalSoftVersion = 0;
            int iBBH = 0;
            mIniFile = new IniFile(Application.StartupPath + "\\update.ini");
            mIniFile.WriteString("Software", "SelfUpdated", "0");
            DataTable dtUpdateSoft = P_Version.GetUpdateVersionList().Tables[0];
            for (int i = 0; i < dtUpdateSoft.Rows.Count; i++)
            {
                sSoftwareName = dtUpdateSoft.Rows[i]["MC"].ToString();
                iBBH = int.Parse(dtUpdateSoft.Rows[i]["BBH"].ToString());
                iLocalSoftVersion = mIniFile.ReadInt("Software", sSoftwareName, 0);
                if ((iBBH > iLocalSoftVersion) && (sSoftwareName != ""))
                {
                    DownOneError = false;
                    try
                    {
                        OutPutMsgAndWriteLog("正在下载更新文件：" + sSoftwareName);
                        string sSoftwareDir = dtUpdateSoft.Rows[i]["LJ"].ToString();
                        string sCurExecuteFileName = System.IO.Path.GetFileName(Application.ExecutablePath);
                        if (sSoftwareDir == "")
                        {
                            OutPutMsgAndWriteLog("sSoftwareName:" + sSoftwareName);

                            if ((sSoftwareName.ToUpper() == sCurExecuteFileName.ToUpper()) ||
                                (sSoftwareName.ToUpper() == "TierService.dll".ToUpper()) ||
                                (sSoftwareName.ToUpper() == "TierApplication.dll".ToUpper()) ||
                                (sSoftwareName.ToUpper() == "DBUtility.dll".ToUpper())
                                )
                            {
                                //_ftpClient.ChangeDir(_ftpInfo.RemotePath);
                                //_ftpClient.Download(sSoftwareDir + "\\" + sSoftwareName, "updatetemp\\");
                                _ftpClient.Download(sSoftwareName, Application.StartupPath+'\\', "$$$" + sSoftwareName + ".$$$");
                                mIniFile.WriteString("Software", "SelfUpdated", "1");
                            }
                            else
                            {
                                _ftpClient.Download( sSoftwareName, Application.StartupPath + "\\");
                            }
                        }
                        else
                        {
                            _ftpClient.Download("\\" + sSoftwareName, Application.StartupPath + "\\" + sSoftwareDir+"\\");
                        }
                        //OutPutMsgAndWriteLog( sSoftwareName + "下载成功");
                    }
                    catch (Exception ex)
                    {
                        OutPutMsgAndWriteLog(string.Format("下载更新文件 {0} 失败。错误信息：{1}", sSoftwareName, ex.Message));
                        DownOneError = true;
                        DownLoadError = true;
                    }
                    if (!DownOneError)
                    {
                        mIniFile.WriteInt("Software", sSoftwareName, iBBH);
                    }
                }
            }
            _isFinishUpdate = true;
            OutPutMsgAndWriteLog("程序更新完毕,更新程序将自动关闭");
            Thread.Sleep(3000);
            this.Invoke(new OnClose(DoClose));//子线程中关闭主线程创建的对象
        }

        private void DoClose()
        {
            Close();
        }

        private void OutPutMsgAndWriteLog(string msg)
        {
            this.Invoke(new OutPutMsgDelegate(this.OutPutMsg), msg);

            File.AppendAllText(LogFileName, msg.Replace("\r\n", ""), Encoding.GetEncoding("gb2312"));
            File.AppendAllText(LogFileName, DateTime.Now.ToString(" yyyy-MM-dd HH:mm:ss"));
            File.AppendAllText(LogFileName, "\r\n");
        }
        private void OutPutMsg(string msg)
        {
            rtxtMsg.AppendText(msg);
            rtxtMsg.AppendText("\r\n");
        }

        private void StartCallBackEXE()
        {
            Process.Start(_callbackEXE);
            Application.Exit();
        }

        private void btnViewLog_Click(object sender, EventArgs e)
        {
            if (File.Exists(LogFileName))
                Process.Start("notepad.exe", Environment.CurrentDirectory + "\\" + LogFileName);
            else
                MessageBox.Show("未找到日志文件！");
        }

        private void FrmUpdate_FormClosing(object sender, FormClosingEventArgs e)
        {
            //if (!_isFinishUpdate)
            //    e.Cancel = true;
        }

        private void frmLiveUpdate_Shown(object sender, EventArgs e)
        {
            P_SysPara mSysPara = new P_SysPara();
            mSysPara.GetModel(Utility.SystemName);
            _ftpInfo = new FtpInfo(mSysPara.FtpServer, "\\" + mSysPara.FtpSoftDir, mSysPara.FtpUser, mSysPara.FtpPwd,int.Parse(mSysPara.FtpPort));

            IniFile mIniFile = new IniFile(Application.StartupPath + "\\update.ini");
             mIniFile.WriteString("Software", "SelfUpdated", "0");

            OutPutMsgAndWriteLog("---------------------------------------------------------------------------");
            if (string.IsNullOrEmpty(_ftpInfo.RemoteHost))
            {
                rtxtMsg.AppendText("自动更新失败！错误信息：参数未设置。");
                rtxtMsg.AppendText("程序将在10秒钟后自动关闭......");
                _isFinishUpdate = true;
                Thread.Sleep(5000);
            }
            else
            {
                th = new Thread(delegate()
                {
                    BeginUpdate();
                });
                th.IsBackground = true;
                th.Start();
                //BeginUpdate();
            }
        }

        private void frmLiveUpdate_FormClosed(object sender, FormClosedEventArgs e)
        {
            IniFile mIniFile = new IniFile(Application.StartupPath + "\\update.ini");
            string sSelfUpdated = mIniFile.ReadString("Software", "SelfUpdated", "1");

            if (sSelfUpdated == "1")
            {
                MessageBox.Show("程序已做更新,系统将重新登录,请稍候");
                StartUpdateBat();
            }
        }

        private void StartUpdateBat()
        {
            string sBatFile = "update.bat";
            string TmpFile = "";
            string NowFile = "";

            string sCurExecuteFileName = System.IO.Path.GetFileName(Application.ExecutablePath);
            if (File.Exists("$$$" + sCurExecuteFileName + ".$$$"))
            {
                TmpFile = "$$$" + sCurExecuteFileName + ".$$$";
                NowFile = sCurExecuteFileName;
            }
            TierService.FileLog.WriteTextToFile("CurExecuteFileName:" + sCurExecuteFileName);

            StreamWriter sw = new StreamWriter(sBatFile);
            sw.WriteLine("@echo off");
            sw.WriteLine(":loop");
            if (TmpFile != "")
            {
                sw.WriteLine("if exist .\\" + TmpFile + " del .\\" + NowFile);
            }
            sw.WriteLine("if exist .\\$$$DBUtility.dll.$$$ del .\\DBUtility.dll");
            sw.WriteLine("if exist .\\$$$TierApplication.dll.$$$ del .\\TierApplication.dll");
            sw.WriteLine("if exist .\\$$$TierService.dll.$$$ del .\\TierService.dll");
            if (TmpFile != "")
            {
                sw.WriteLine("if exist .\\" + TmpFile + " if exist .\\" + NowFile + " goto loop");
            }
            sw.WriteLine("if exist .\\" + "$$$DBUtility.dll.$$$" + " if exist .\\" + "DBUtility.dll" + " goto loop");
            sw.WriteLine("if exist .\\" + "$$$TierApplication.dll.$$$" + " if exist .\\" + "TierApplication.dll" + " goto loop");
            sw.WriteLine("if exist .\\" + "$$$TierService.dll.$$$" + " if exist .\\" + "TierService.dll" + " goto loop");
            sw.WriteLine("copy .\\$$$DBUtility.dll.$$$ .\\DBUtility.dll");
            sw.WriteLine("del .\\$$$DBUtility.dll.$$$");
            sw.WriteLine("copy .\\$$$TierApplication.dll.$$$ .\\TierApplication.dll");
            sw.WriteLine("del .\\$$$TierApplication.dll.$$$");
            sw.WriteLine("copy .\\$$$TierService.dll.$$$ .\\TierService.dll");
            sw.WriteLine("del .\\$$$TierService.dll.$$$");
            if (TmpFile != "")
            {
                sw.WriteLine("copy .\\" + TmpFile + "  .\\" + NowFile);
                sw.WriteLine("del .\\" + TmpFile);
            }

            IniFile mIniFile = new IniFile(Application.StartupPath + "\\update.ini");
            string sSelfUpdated = mIniFile.ReadString("Software", "SelfUpdated", "1");
            if (sSelfUpdated == "1")
            {
                sw.WriteLine("start " + NowFile);
            }
            sw.WriteLine("CLS");
            sw.WriteLine("del .\\" + sBatFile);
            sw.Flush();
            sw.Close();
            if (File.Exists(sBatFile))
            {
                //Process.Start(sBatFile);
                Process proc = new Process();
                proc.StartInfo.FileName = sBatFile;
                proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                proc.StartInfo.ErrorDialog = false;
                //proc.StartInfo.WorkingDirectory = Path.GetDirectoryName(Application.StartupPath);
                proc.Start();
                //proc.WaitForExit();
                Environment.Exit(0);
            }

        }
    }
}